package com.maimao.goods.controller;

import cn.hutool.core.util.ObjectUtil;
import com.maimao.api.mall.goods.GoodsApi;
import com.maimao.core.model.auth.AuthUser;
import com.maimao.core.model.resp.PageResult;
import com.maimao.core.model.resp.Result;
import com.maimao.goods.callback.kafka.callback.PublishCallback;
import com.maimao.goods.client.EsDocClient;
import com.maimao.goods.client.ShopClient;
import com.maimao.goods.controller.base.BaseController;
import com.maimao.goods.service.GoodsService;
import com.maimao.goods.service.SkuService;
import com.maimao.message.kafka.sender.KafkaSender;
import com.maimao.model.goods.Goods;
import com.maimao.model.goods.GoodsSku;
import com.maimao.model.goods.input.GoodsSearch;
import com.maimao.model.goods.vo.*;
import com.maimao.model.info.Collect;
import com.maimao.model.info.vo.FollowGoods;
import com.maimao.model.kill.input.ApplySkuNewInput;
import com.maimao.model.user.Foot;
import com.maimao.model.user.Shop;
import io.seata.core.context.RootContext;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;

import static com.maimao.core.constant.AuthKey.COMPANY;
import static com.maimao.core.constant.AuthKey.MEMBER;

/**
 * @author MaoLin Wang
 * @date 2020/12/22 11:52 上午
 */
@RestController
public class GoodsController extends BaseController implements GoodsApi {
    private static final Integer DEFAULT_NEW_GOODS_DAY_LIMIT = 30;
    private Logger log = LoggerFactory.getLogger(GoodsController.class);
    @Autowired
    private KafkaSender kafkaSender;
    @Value("${maimao.kafka.topic.publish}")
    private String publishTopic;
    @Autowired
    private EsDocClient esDocClient;

    @Autowired
    private ShopClient shopClient;

    @Autowired
    private SkuService skuService;


    @PostMapping("/publish")
    @Override
    public Result<?> publish(@Valid @RequestBody GoodsPublish goodsPublish, BindingResult bindingResult) {
       /* if (bindingResult.hasErrors()) {
            return entityInvalid(bindingResult);
        }*/
        AuthUser authUser = checkAndGetAuthUser();

        goodsService.publish(goodsPublish, authUser);
        return Result.ok();
    }

    @Override
    @PostMapping("/updateBaby")
    public Result<?> updateBaby(@Valid @RequestBody GoodsPublish goodsPublish, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return entityInvalid(bindingResult);
        }
        AuthUser authUser = checkAndGetAuthUser();
        if (goodsPublish.getGoods().getId() == null || goodsPublish.getGoods().getId() <= 0 || goodsPublish.getGoods().getShopId() == null || goodsPublish.getGoods().getShopId() <= 0) {
            return Result.notValid();
        }

        return goodsService.updateBaby(goodsPublish, authUser);
    }

    @PostMapping("/kafka/{id}")
    public Result<?> kafka(@PathVariable("id") String id) {
        kafkaSender.sendCallBack(publishTopic, String.valueOf(id), String.valueOf(id), new PublishCallback(publishTopic, Long.valueOf(id), kafkaSender, esDocClient));
        return Result.ok();
    }


    /**
     * 分页查询商品详细信息
     *
     */
    @Override
    @GetMapping("/goodsinfo")
    public Result<?> goodsInfoPage(@RequestParam(value = "page", defaultValue = "1") Integer page, @RequestParam(value = "size", defaultValue = "10") Integer size) {
        if (page < 1) {
            page = 1;
        }
        if (size < 1) {
            size = 5;
        }
        return Result.okData(goodsService.goodsInfoPage(page, size));
    }

    /**
     * Kafka消费者异步调用Feign时使用 无认证信息 暂时放行
     *
     * @param goodsId 商品ID
     */
    @Override
    @GetMapping("/goodsinfo-byid")
    public Result<?> goodsInfoPageByGoodsId(@RequestParam(value = "goodsId") Long goodsId) {
        if (goodsId == null || goodsId < 1) {
            return Result.notValid();
        }
        String requestURI = getRequest().getRequestURI();
        log.info(String.valueOf(getRequest().getRemoteAddr()));
        log.info(requestURI);
        return Result.okData(goodsService.goodsInfoPageByGoodsId(goodsId));
    }

    /**
     * 商品详情页数据
     *
     * @param goodsId 商品id
     */
    @Override
    @GetMapping("/detail/{id}")
    public Result<?> detailPage(@PathVariable("id") String goodsId) {
        if (StringUtils.isEmpty(goodsId) || Long.valueOf(goodsId) <= 0) {
            return Result.notValid();
        }
        AuthUser authUser = getAuthUser();

        GoodsPage goodsPage = goodsService.goodDetailPage(Long.valueOf(goodsId), authUser == null ? null : Long.valueOf(authUser.getId()));
        if (goodsPage == null) {
            return Result.notValid("宝贝已经下架或后台审核中");
        }
        return Result.okData(goodsPage);
    }

    /**
     * 商品详情数据（后台审核商品查看商品信息，不包含优惠券、店铺等信息）
     *
     * @param goodsId
     */
    @Override
    @GetMapping("/ms-check-detail/{id}")
    @PreAuthorize("hasAuthority('goods-manager')")
    public Result<?> goodsCheckInfo(@PathVariable("id") String goodsId) {
        if (StringUtils.isEmpty(goodsId) || Long.valueOf(goodsId) <= 0) {
            return Result.notValid();
        }
        AuthUser authUser = checkAndGetAuthUser();

        GoodsPage goodsPage = goodsService.goodsCheckDetail(Long.valueOf(goodsId));
        if (goodsPage == null) {
            return Result.notValid("宝贝已不存在~");
        }
        return Result.okData(goodsPage);
    }

    /**
     * 店铺发布优惠券时选择优惠商品 根据店铺id查询所有商品（id+名称）
     */
    @Override
    @GetMapping("/goods-shop-simple")
    public Result<?> querySimpleByShop(@RequestParam(value = "shopId", required = false) Long shopId,
                                       @RequestParam("key") String key,
                                       @RequestParam(value = "page", defaultValue = "1") Integer page,

                                       @RequestParam(value = "size", defaultValue = "15") Integer size) {
        AuthUser authUser = checkAndGetAuthUser();
        shopId = authUser.getShopId();
        PageResult<Goods> goodsData = goodsService.querySimpleByShop(shopId, key, page, size, authUser == null ? null : authUser.getId());
        return Result.okData(goodsData);
    }

    /**
     * 检查sku是否有效（商品是否下架 库存是否大于0）
     */
    @GetMapping("/client/checkSku")
    @Override
    public Result<?> checkSku(@RequestParam("skuId") Long skuId) {
        if (skuId == null || skuId <= 0) {
            return Result.notValid();
        }
        Boolean res = goodsService.checkSku(skuId);
        return Result.okData(res);
    }

    /**
     * 批量检查sku是否有效（商品是否下架 库存是否大于0且满足下单量） 下单时调用
     *
     * @param data key:skuId value:下单量
     */
    @Override
    @PostMapping("/check-sku-batch")
    public Result<?> checkSkuBatch(@RequestBody Map<Long, Integer> data) {
        if (data == null || data.size() <= 0) {
            return Result.notValid();
        }
        boolean res = skuService.checkSkuBatch(data);
        return Result.okData(res);
    }

    /**
     * 批量检查sku是否有效（商品是否下架 库存是否大于0且满足下单量）返回无效的skuID
     *
     */
    @PostMapping("/check-sku-batch-res")
    public Result<?> checkSkuBatchWithRes(@RequestBody List<Long> skuIds) {
        if (ObjectUtil.isEmpty(skuIds)) {
            return Result.notValid();
        }
        List<Long> res = skuService.checkSkuBatchWithRes(skuIds);
        return Result.okData(res);
    }

    /**
     * 检查spu是否有效（商品是否下架） 下单时调用
     *
     * @param goodsIdList 商品ID列表
     */
    @PostMapping("/check-spu-batch")
    @Override
    public Result<?> checkSpuBatch(@RequestBody List<Long> goodsIdList) {
        if (goodsIdList == null || goodsIdList.size() <= 0) {
            return Result.notValid();
        }
        boolean res = goodsService.checkSpuBatch(goodsIdList);
        return Result.okData(res);
    }

    /**
     * 根据商品id查询品牌id
     */
    @GetMapping("/client/queryBrandIdByGid")
    @Override
    public Result<?> queryBrandIdByGoodsId(@RequestParam("goodsId") Long goodsId) {
        if (goodsId == null || goodsId <= 0) {
            return Result.notValid();
        }
        Long brandId = goodsService.queryBrandIdByGoodsId(goodsId);
        return Result.okData(brandId);
    }

    /**
     * 插件sku是否为新上架的
     *
     * @param input
     * @return 返回新上架的skuId列表
     */
    @PostMapping("/client/checkSkuIsNew")
    public Result<?> checkSkuIsNew(@RequestBody ApplySkuNewInput input) {
        if (input.getFromTime() == null || input.getSkuIds() == null) {
            return Result.notValid();
        }

        return Result.okData(goodsService.checkSkuNew(input.getSkuIds(), input.getFromTime()));
    }

    /**
     * 批量更新sku信息（这里为审核秒杀商品信息后更新sku秒杀信息）
     *
     * @param skus
     * @return
     */
    @PostMapping("/client/updateSkuBatch")
    public Result<?> updateSkuBatch(@RequestBody List<GoodsSku> skus) {
        skuService.updateBatch(skus);
        return Result.ok();
    }

    /**
     * 批量查询秒杀sku信息
     */
    @PostMapping("/client/skuKillInfoBatch")
    public Result<?> getSkuKillInfoBatch(@RequestBody List<Long> skuIds) {
        return Result.okData(skuService.selectKillInfoBatch(skuIds));
    }

    /**
     * 下单修改库存
     *
     * @param oper     1:下单减库存 0：取消订单加库存
     * @param stockMap key:skuId value:购买数量
     * @return
     */
    @Override
    @PostMapping("/client/updateStock")
    public Result<?> updateStock(@RequestParam("oper") Integer oper, @RequestBody Map<Long, Integer> stockMap) {
        if (oper == null || (!oper.equals(1) && !oper.equals(0)) || stockMap == null || stockMap.size() <= 0) {
            return Result.notValid();
        }
        HttpServletRequest request = getRequest();
        String xid = request.getHeader(RootContext.KEY_XID);
        RootContext.bind(xid);
        goodsService.updateStock(oper, stockMap);
        return Result.ok();
    }

    /**
     * 增加销量 （下单时调用）
     *
     * @param sellCountMap key:商品id value:要增加的销量
     */
    @Override
    @PostMapping("/add-sellCount")
    public Result<?> addSellCount(@RequestBody Map<Long, Integer> sellCountMap) {
        if (sellCountMap == null || sellCountMap.size() <= 0) {
            return Result.notValid();
        }
        bindXid();

        goodsService.addSellCount(sellCountMap);
        return Result.ok();
    }

    /**
     * 修改上下架状态
     *
     * @param sellStatusMap key:商品id value：onSell状态 1：上架  0 下架
     * @return
     */
    @Override
    @PostMapping("/update-onSell")
    public Result<?> updateSellStatus(@RequestBody Map<String, String> sellStatusMap) {
        if (sellStatusMap == null) {
            return Result.notValid();
        }
        Long goodsId = Long.valueOf(sellStatusMap.get("id"));
        Integer onSell = Integer.valueOf(sellStatusMap.get("status"));
        if (goodsId == null || onSell == null || goodsId <= 0 || (!onSell.equals(1) && !onSell.equals(0))) {
            return Result.notValid();
        }
        goodsService.updateSellStatus(goodsId, onSell);
        return Result.ok();
    }


    /**
     * 商家商品列表 —— 报名秒杀选择sku时也会调用
     */
    @Override
    @PostMapping("/shop-goods-list")
    public Result<?> shopGoodsList(@RequestBody GoodsSearch goodsSearch,
                                   @RequestParam(value = "page", defaultValue = "1") Integer page,
                                   @RequestParam(value = "size", defaultValue = "8") Integer size) {
        AuthUser authUser = checkAndGetAuthUser();
        Result<Shop> shopRes = null;
        if (authUser.getRole().equals(COMPANY)) {
            //企业用户
            shopRes = shopClient.findShopByOwner(authUser.getId2Long(), 1);
        } else if (authUser.getRole().equals(MEMBER)) {
            //普通用户
            shopRes = shopClient.findShopByOwner(authUser.getId2Long(), 0);
        } else {
            return Result.notValid("非法用户");
        }
        if (shopRes == null || shopRes.getData() == null || shopRes.getData().getId() == null || shopRes.getData().getId() <= 0) {
            return Result.notValid("您尚未开通店铺");
        }
        PageResult<GoodsVo> res = goodsService.shopGoodsList(shopRes.getData().getId(), goodsSearch, page, size);
        return Result.okData(res);
    }

    /**
     * 用户足迹
     *
     * @param goodsIdList
     * @return
     */
    @Override
    @PostMapping("/foot-goods")
    public Result<?> userFoot(@RequestBody List<Long> goodsIdList) {
        if (goodsIdList == null || goodsIdList.size() <= 0) {
            return Result.notValid();
        }
        return Result.okData(goodsService.userFoot(goodsIdList));
    }

    /**
     * 用户关注的商品
     *
     * @param collectList
     * @return
     */
    @Override
    @PostMapping("/follow-goods")
    public Result<?> followGoods(@RequestBody List<Collect> collectList) {
        if (collectList == null || collectList.size() <= 0) {
            return Result.notValid();
        }
        return Result.okData(goodsService.followGoods(collectList));
    }

    /**
     * 后台商品统计记录
     *
     * @return
     */
    @GetMapping("/data-overview")
    @Override
    public Result<?> msGoodsOverView() {
        GoodsCountVo goodsCountVo = goodsService.msGoodsOverView();
        return Result.okData(goodsCountVo);
    }

    /**
     * 点击商品 增加点击量
     *
     * @param goodsId
     * @return
     */
    @GetMapping("/click-goods")
    public void addClick(@RequestParam("goodsId") String goodsId) {
        if (StringUtils.isBlank(goodsId)) {
            return;
        }
        goodsService.addClick(goodsId);
        return;
    }

    @Autowired
    private GoodsService goodsService;
}
